package bsk_dac;

import bsk_dac.accesscontrol.TableAccess;
import bsk_dac.accesscontrol.UserAccess;
import bsk_dac.actions.SelectingPrivileges;
import bsk_dac.actions.SelectingUser;
import bsk_dac.database.DatabaseFacade;
import bsk_dac.database.DatabaseUser;
import bsk_dac.database.SelectingDatabaseUserFrame;
import bsk_dac.tables.TablesManager;
import bsk_dac.users.User;
import bsk_dac.users.UsersManager;
import java.awt.Color;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import sun.applet.Main;

public class DACPanel extends javax.swing.JPanel {
     public MainDACFrame mainDACFrame;
    private SelectingUser selectingUser;
    private SelectingPrivileges selectingPrivileges;
    private ArrayList<UserPanel> usersPanels;
    private Map<User, ArrayList<PrivilegesPanel>> usersRow;

    /** Creates new form DACPanel */
    public DACPanel(MainDACFrame mainDacFrame) {
        initComponents();
        this.mainDACFrame = mainDacFrame;
        usersPanels = new ArrayList<UserPanel>();
        selectingUser = new SelectingUser(usersPanels, this);
        usersRow = new HashMap<User, ArrayList<PrivilegesPanel>>();
        selectingPrivileges = new SelectingPrivileges(this);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();

        setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Macierz uprawnień", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 18))); // NOI18N
        setPreferredSize(new java.awt.Dimension(620, 460));
        setLayout(new java.awt.GridLayout(1, 0));

        jLabel1.setFont(new java.awt.Font("DejaVu Sans", 0, 18)); // NOI18N
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Użytkownicy \\ Tabele");
        jLabel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        add(jLabel1);

        jLabel2.setBackground(new java.awt.Color(235, 235, 235));
        jLabel2.setFont(new java.awt.Font("DejaVu Sans", 0, 18)); // NOI18N
        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel2.setText("Sections");
        jLabel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        add(jLabel2);

        jLabel3.setFont(new java.awt.Font("DejaVu Sans", 0, 18)); // NOI18N
        jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel3.setText("Topics");
        jLabel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        add(jLabel3);

        jLabel4.setFont(new java.awt.Font("DejaVu Sans", 0, 18)); // NOI18N
        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel4.setText("Posts");
        jLabel4.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        add(jLabel4);
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    // End of variables declaration//GEN-END:variables

    public void clear() {
        for (UserPanel userPanel : usersPanels) {
            ArrayList<PrivilegesPanel> panels = usersRow.get(userPanel.getUser());
            for (PrivilegesPanel panel : panels) {
                this.remove(panel);
            }
            this.remove(userPanel);
        }

        usersPanels = new ArrayList<UserPanel>();
        selectingUser = new SelectingUser(usersPanels, this);
        usersRow = new HashMap<User, ArrayList<PrivilegesPanel>>();
        selectingPrivileges = new SelectingPrivileges(this);
    }

    public void addUserPanel(User user) {
        UserPanel userNamePanel = new UserPanel(this);

        userNamePanel.setUser(user);
        userNamePanel.setUserName();
        userNamePanel.refreshAccessView();

        addListenerToUserPanelToggleBtn(userNamePanel);
        usersPanels.add(userNamePanel);
        add(userNamePanel);
    }

    public void addPrivilegesPanel(String tableName, User user) {
        PrivilegesPanel privilegesPanel = new PrivilegesPanel(user, tableName);
        TableAccess access = user.getTableAccess(tableName);

        addAccessToPrivilegesPanel(privilegesPanel, access);

        addListenerToPrivilegesPanelCheckBoxes(privilegesPanel);
        addPrivilegesPanelToUserRow(user, privilegesPanel);
        add(privilegesPanel);
    }

    public Map<User, ArrayList<PrivilegesPanel>> getUsersRow() {
        return usersRow;
    }

    public ArrayList<UserPanel> getUsersPanels() {
        return usersPanels;
    }



    public void refreshPanelsAccess() {
        if (MainDACFrame.getUsersManager().getSelectedUser() != null) {
            givePrivileges();
        } else {
            adminMode();
        }
        for (UserPanel userPanel : usersPanels) {
            userPanel.refreshAccessView();
        }
    }

    private void adminMode() {
        TablesManager tableManager = TablesManager.getTableManager();
        ArrayList<String> tablesNames = tableManager.getAvaiableTables();

        for (User user : usersRow.keySet()) {
            ArrayList<PrivilegesPanel> privilegesPanels = usersRow.get(user);
            for (int i = 0; i < tablesNames.size(); i++) {
                TableAccess access = user.getTableAccess(tablesNames.get(i));
                PrivilegesPanel panel = privilegesPanels.get(i);
                panel.setCheckboxState(access, false, false, true);
                panel.setEnabledAllCheckboxes(true);
            }
        }
    }

    public void givePrivileges() {
        User selectedUser = MainDACFrame.getUsersManager().getSelectedUser();
        setCheckboxStatusForOtherUsers(selectedUser);
        setDisabledCheckboxStatusForUser(selectedUser);
    }

    public void markUserRow(User user, Color color) {
        ArrayList<PrivilegesPanel> panels = usersRow.get(user);
        for (PrivilegesPanel panel : panels) {
            panel.setBackground(color);
        }
    }

    private void addAccessToPrivilegesPanel(PrivilegesPanel privilegesPanel, TableAccess access) {
        privilegesPanel.setAccess(access);
        privilegesPanel.refreshAccessView();
    }

    private void addPrivilegesPanelToUserRow(User user, PrivilegesPanel privilegesPanel) {
        initializePrivilegesPanelListForUserInUserRows(user);
        usersRow.get(user).add(privilegesPanel);
    }

    private void initializePrivilegesPanelListForUserInUserRows(User user) {
        if (!usersRow.containsKey(user)) {
            usersRow.put(user, new ArrayList<PrivilegesPanel>());
        }
    }

    private void addListenerToUserPanelToggleBtn(UserPanel userPanel) {
        userPanel.addActionListenerToToggleBtn(selectingUser);
    }

    private void addListenerToPrivilegesPanelCheckBoxes(PrivilegesPanel privilegesPanel) {
        privilegesPanel.getSelectCB().addActionListener(selectingPrivileges);
        privilegesPanel.getUpdateCB().addActionListener(selectingPrivileges);
        privilegesPanel.getDeleteCB().addActionListener(selectingPrivileges);
        privilegesPanel.getInsertCB().addActionListener(selectingPrivileges);
    }

    private void setDisabledCheckboxStatusForUser(User selectedUser) {

        TablesManager tableManager = TablesManager.getTableManager();
        ArrayList<String> tablesNames = tableManager.getAvaiableTables();

        ArrayList<PrivilegesPanel> privilegesPanels = usersRow.get(selectedUser);
        for (int i = 0; i < tablesNames.size(); i++) {
            TableAccess access = selectedUser.getTableAccess(tablesNames.get(i));
            PrivilegesPanel panel = privilegesPanels.get(i);
            panel.setEnabledAllCheckboxes(false);
            panel.setCheckboxState(access, false, true, true);
        }
    }

    private void setCheckboxStatusForOtherUsers(User selectedUser) {
        try {
            TablesManager tableManager = TablesManager.getTableManager();
            ArrayList<String> tablesNames = tableManager.getAvaiableTables();

            int selectedUserId = DatabaseFacade.getUserId(selectedUser.getUserName());
            int otherUserId = -1;
            int tableId = -1;
            ArrayList<String> permissionNames = null;

            for (User user : usersRow.keySet()) {
                ArrayList<PrivilegesPanel> privilegesPanels = usersRow.get(user);
                otherUserId = DatabaseFacade.getUserId(user.getUserName());
                for (int i = 0; i < tablesNames.size(); i++) {
                    tableId = DatabaseFacade.getTableId(tablesNames.get(i));
                    TableAccess access = selectedUser.getTableAccess(tablesNames.get(i));
                    PrivilegesPanel panel = privilegesPanels.get(i);
                   
                   // panel.setBlackAllCheckboxes();
                    //panel.setEnabledAllCheckboxes(true);
                    panel.setSelectedAllCheckboxes(false);
                    panel.setCheckboxState(access, false, true, false);
                    panel.hideRed(access);
                    panel.hideSelected();
                    
                    permissionNames = DatabaseFacade.getPermissionNamesInHistory(selectedUserId, otherUserId, tableId);
                    panel.setGreenPermissions(permissionNames);
                }
            }
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}
